import { isObject } from "lodash-es";
import { ElementType } from "../types";
import { h } from "vue";

export class ElementManager {
  private cache = {}
  private viewCache = {}

  constructor() {
    this.initElements()
    this.initViewElements()
  }

  private initElements() {
    const modules: Record<string, any> = import.meta.glob('/src/seed-application/elements/**', { eager: true });
    for(const path in modules) {
      const fileName = path.substring(path.lastIndexOf('/') + 1)
      if(['index.ts', 'index.js'].includes(fileName)) continue
      
      const ext = path.substring(path.lastIndexOf('.') + 1)
      this.cache[path.substring('/src/seed-application/elements/'.length, path.length - `.${ext}`.length)] = modules[path]['default']
    }
    console.log('seed-elements', this.cache)
  }

  private initViewElements() {
    const modules: Record<string, any> = import.meta.glob('/src/views/elements/**', { eager: true });
    for(const path in modules) {
      const fileName = path.substring(path.lastIndexOf('/') + 1)
      if(['index.ts', 'index.js'].includes(fileName)) continue
      
      const ext = path.substring(path.lastIndexOf('.') + 1)
      this.viewCache[path.substring('/src/views/elements/'.length, path.length - `.${ext}`.length)] = modules[path]['default']
    }
  }

  public getElement(elementType: ElementType, type: 'read' | 'write' | 'set' = 'read', name?: string){
    if(!name) {
      const key = `${elementType}/${defaultElements[elementType]?.[type]}`
      return this.viewCache[key] || this.cache[key] || LostComponent(elementType)
    }
    if(isObject(name)) return name

    const key = `${elementType}/${name}`
    return this.viewCache[key] || this.cache[key] || LostComponent(elementType, name)
  }
}

const defaultElements: Record<ElementType, Record<'read' | 'write' | 'set', string>> = {
  varchar: {read: 'Default', write: 'Input', set: 'Input'},
  char: {read: 'Default', write: 'Default', set: 'Default'},
  tinytext: {read: 'Default', write: 'Textarea', set: 'Textarea'},
  text: {read: 'Default', write: 'Textarea', set: 'Textarea'},
  mediumtext: {read: 'Default', write: 'Textarea', set: 'Textarea'},
  longtext: {read: 'Default', write: 'Textarea', set: 'Textarea'},
  tinyint: {read: 'Default', write: 'InputNumber', set: 'InputNumber'},
  smallint: {read: 'Default', write: 'InputNumber', set: 'InputNumber'},
  mediumint: {read: 'Default', write: 'InputNumber', set: 'InputNumber'},
  int: {read: 'Default', write: 'InputNumber', set: 'InputNumber'},
  bigint: {read: 'Default', write: 'InputNumber', set: 'InputNumber'},
  double: {read: 'Default', write: 'InputNumber', set: 'InputNumber'},
  float: {read: 'Default', write: 'InputNumber', set: 'InputNumber'},
  decimal: {read: 'Default', write: 'InputNumber', set: 'InputNumber'},
  bit: {read: 'Default', write: 'Switch', set: 'Switch'},
  enum: {read: 'Default', write: 'Select', set: 'Select'},
  set: {read: 'Default', write: 'Select', set: 'Select'},
  date: {read: 'Default', write: 'Date', set: 'Calendar'},
  year: {read: 'Default', write: 'Date', set: 'Calendar'},
  datetime: {read: 'Default', write: 'Date', set: 'Calendar'},
  timestamp: {read: 'Default', write: 'Date', set: 'Calendar'},
  file: {read: 'Default', write: 'Input', set: 'Input'},
  image: {read: 'Default', write: 'Input', set: 'Input'},
  avatar: {read: 'Default', write: 'Upload', set: 'Upload'},
  password: {read: 'Default', write: 'Input', set: 'Input'},
  icon: {read: 'Default', write: 'Input', set: 'Input'},
  qrcode: {read: 'Default', write: 'Input', set: 'Input'},
  tinyblob: {read: 'Default', write: 'Input', set: 'Input'},
  blob: {read: 'Default', write: 'Input', set: 'Input'},
  mediumblob: {read: 'Default', write: 'Input', set: 'Input'},
  longblob: {read: 'Default', write: 'Input', set: 'Input'},
  binary: {read: 'Default', write: 'Input', set: 'Input'},
  varbinary: {read: 'Default', write: 'Input', set: 'Input'},
  json: {read: 'Default', write: 'Input', set: 'Input'},
  color: {read: 'Default', write: 'Input', set: 'Input'},
  ref: {read: 'Default', write: 'LookupPage', set: 'PagePanel'},
  yesno: {read: 'Default', write: 'Checkbox', set: 'Checkbox'},
  sex: {read: 'Default', write: 'Input', set: 'Input'},
  age: {read: 'Default', write: 'Input', set: 'Input'},
  // code: {read: 'DefaultCode', write: 'InputCode', set: 'InputCode'},
  // account: {read: 'DefaultAccount', write: 'InputAccount', set: 'InputAccount'}
}

function LostComponent(type?: ElementType, element?: string) {
  if(!type) return {setup: () => () => h('div', {description: '【无】'})}
  if(!element) return {setup: () => () => h('div', `【${type}】`)}
  return {setup: () => () => h('div', `【${type}.${element}】`)}
}